# -*- utf8 -*-

import math
import sys
from bisect import bisect
import hashlib
import mmh3

# python实现
# https://github.com/Doist/hash_ring/blob/7cb52f91c7d78a633c730bd031432d96f1601e3c/hash_ring/ring.py#L164
# cpp
# https://github.com/metang326/consistent_hashing_cpp
# https://github.com/christophetcheng/ConsistentHash/blob/master/src/consistenthash/ConsistentHashImpl.cpp
# https://github.com/anchorhash/cpp-anchorhash
# https://github.com/shuaidong1996/Consistent-Hashing
# https://github.com/phaistos-networks/ConsistentHashing
# https://github.com/ioriiod0/consistent_hash
# https://github.com/search?l=Python&q=consistent_hash&type=Repositories

class ConsistentHash:
    def __init__(self) -> None:
        self.nodes = []    # 原始节点信息
        self.weights = []  # 权重信息
        self.sorted_tag = []
        #self.ring = dict()

    def add_node(self, node, weight):
        '''
        @brief: 添加一个节点
        '''
        self._rebuild_circle()

    def add_nodes(self, nodes:list, weights:list):
        '''
        @brief: 添加N个节点
        '''
        self._rebuild_circle()
        
    def get_node(self, hash_key):
        '''
        @brief: 使用指定的key获取当前对象管理的哈希节点
        '''

    def _rebuild_circle(self):
        '''
        @brief: 重建哈希环(重新分配节点到2^32个slot上)
        '''
        #for idx in range(0, )
        idx = 0
        for node in self.nodes:
            ring_idx = 0

    def _node_2_hash(self, node, salt = None):
        '''
        @brief: node对象转为哈希值
        '''
        # node转为可以进行MD5哈希运算的数据（二进制或者字符串）
        md5encoder = hashlib.md5()
        md5encoder.update(bytes(str(node) + str(salt), "utf-8"))
        ## 返回大写哈希字符串：32个字符
        #md5encoder.hexdigest().upper()
        # 返回二进制MD5值：16BYTE
        return md5encoder.digest()

    def _bytes_2_ring_solt(self, datas:bytes):
        '''
        @brief: 哈希值转为ring上的节点
        '''
        MAX_UINT = 0xffffffff
        solt_key = 0
        # 累加
        # idx = 0
        # for bt in datas:
        #     if idx > (4 - 1) * 8:
        #         idx = 0
        #     else:
        #         idx += 8
        #     solt_key += (bt << idx)
        #     idx += 1
        # solt_key = solt_key % MAX_UINT

        # 直接取四位合成
        #solt_key = datas[0] | (datas[1] << 8) | (datas[2] << 16) | (datas[3] << 24)
        
        # for bt in datas:
        #     solt_key = 2166136261
        #     solt_key ^= bt
        #     solt_key %= MAX_UINT
        #     solt_key *= 16777619
        #     solt_key %= MAX_UINT
        
        solt_key = mmh3.hash(datas, signed = False)
        
        return solt_key

if __name__ == "__main__":
    solt_set = set()
    consistent_hash = ConsistentHash()
    solt_list = []
    max_cnt = 6
    for n in range(0, max_cnt):
        #solt_key = consistent_hash._bytes_2_ring_solt(consistent_hash._node_2_hash(str(n)))
        solt_key = consistent_hash._bytes_2_ring_solt(bytes(str(n), "utf-8"))
        #print(solt_key)
        if solt_key not in solt_set:
            solt_set.add(solt_key)
            solt_list.append(solt_key)
        else:
            print("repeat: ", n, solt_key)
    print(solt_set)
    print("total solt count is: ", len(solt_set))
    solt_list = sorted(solt_list)
    print(solt_list)
    idx = 0
    for solt in solt_list:
        if idx == 0:
            print(solt)
        else:
            print(solt - solt_list[idx - 1])
        idx += 1